﻿Imports System.Timers

'Базовый класс
Public Class BaseMobile

#Region "свойства"
    'цвет телефона
    Private _color() As String
    Public Property Color() As String()
        Get
            Return _color
        End Get
        Set(ByVal value As String())
            _color = value
        End Set
    End Property
    'индексированное свойство
    Public Property Color(ByVal index As Integer) As String
        Get
            Return _color(index)
        End Get
        Set(ByVal value As String)
            _color(index) = value
        End Set
    End Property

    'включен ли телефон
    Private _isOn As Boolean
    Public Property IsOn As Boolean
        Get
            Return _isOn
        End Get
        Set(ByVal value As Boolean)
            _isOn = value
        End Set
    End Property

    'телефон заряжается
    Private _isCharging
    Public Property IsCharging As Boolean
        Get
            Return _isCharging
        End Get
        Set(ByVal value As Boolean)
            _isCharging = value
        End Set
    End Property

    'будильник активирован
    Private _ringIsSet As Boolean
    Public Property RingIsSet As Boolean
        Get
            Return _ringIsSet
        End Get
        Set(ByVal value As Boolean)
            _ringIsSet = value
        End Set
    End Property

    'есть ли сенсорный экран
    Private _hasSensorScreen As Boolean
    Public Property HasSensorScreen As Boolean
        Get
            Return _hasSensorScreen
        End Get
        Set(ByVal value As Boolean)
            _hasSensorScreen = value
        End Set
    End Property

    'список сообщений
    Private _messageList As New List(Of SMSMessage)
    Public Property MessageList As List(Of SMSMessage)
        Get
            Return _messageList
        End Get
        Set(ByVal value As List(Of SMSMessage))
            _messageList = value
        End Set
    End Property
    Public Property MessageList(ByVal index As Integer) As SMSMessage
        Get
            Return _messageList(index)
        End Get
        Set(ByVal value As SMSMessage)
            _messageList(index) = value
        End Set
    End Property

    'уровень заряда
    Private _batteryLevel As Integer
    Public Property BatteryLevel() As Integer
        Get
            Return _batteryLevel 'возвращает значение свойства/получаем значение переменной,которое будет значением и свойства
        End Get
        Set(ByVal value As Integer) 'устанавливает значение свойства, включая ссылку на объект.вызывается при присвоении значения свойству
            If (value < _minBatteryLevel Or value > _maxBatteryLevel) Then
                MsgBox("Значения зарядки может быть в диапазоне от 0 до 100")
                Return
            End If
            _batteryLevel = value 'Параметр value представляет передаваемое значение.
            RaiseEvent BatteryLevelChangedEvent(Me, New System.EventArgs()) 'вызывает событие
        End Set
    End Property

    'время будильника
    Private _ringTime As DateTime
    Public Property RingTime() As DateTime
        Get
            Return _ringTime
        End Get
        Set(ByVal value As DateTime)
            _ringTime = value.ToString("HH:mm")
        End Set
    End Property

    'звонит ли будильник
    Private _IsRingBelling As Boolean
    'звук маленького уровня заряда
    Private _isLowBatteryPlayed As Boolean
    'проигрыватель звуков
    Friend WithEvents _player As WMPLib.WindowsMediaPlayer
    'маленький заряд батареи
    Private _isLowBattery As Boolean
    'таймер разрядки телефона
    Private _timer As Timer
    'таймер проверки будильник
    Private _ringTimer As Timer
    'таймер получения сообщений
    Private _messageTimer As Timer
    'время активации будильник
    Private _timerStartTime As DateTime
    'генератор сообщений
    Protected Friend _generator As New MessageGenerator
    'показывалось ли  о разрядке
    Private _isBatteryLowMsgShown As Boolean
    'минимальное значение заряда телефона
    Private _minBatteryLevel As Byte
    'максимальное значение заряда телефона
    Private _maxBatteryLevel As Byte

#End Region

#Region "конструктор"
    Public Sub New()
        HasSensorScreen = False
        Color = {"Красный", "Синий", "Голубой"}
        IsOn = False 'включен ли телефон
        Init()

        _player = New WMPLib.WindowsMediaPlayer

        _timer = New Timer(2000) 'таймер разрядки тел
        AddHandler _timer.Elapsed, New ElapsedEventHandler(AddressOf ChargeHandler) 'связывает событие с обработчиком события разрядки батареи

        _ringTimer = New Timer
        _ringTimer.Interval = 1000
        _ringTimer.Enabled = False 'включен ли таймер проверки будильника
        AddHandler _ringTimer.Elapsed, New ElapsedEventHandler(AddressOf CheckRingBellTime)

        _messageTimer = New Timer
        _messageTimer.Interval = 10000
        _messageTimer.Enabled = False
        AddHandler _messageTimer.Elapsed, New ElapsedEventHandler(AddressOf CheckMessageRecieve)

        AddHandler Me.BatteryLow, AddressOf OnBatteryLow
    End Sub
#End Region

#Region "методы"

    Public Sub Init()
        MessageList = New List(Of SMSMessage)
        _minBatteryLevel = 1
        _maxBatteryLevel = 100
        'заполняем случайно уровень батареи 30<х<100
        Dim rand As New Random
        BatteryLevel = rand.Next(30, 100)

        'настройки будильника
        _IsRingBelling = False
        _isLowBatteryPlayed = False
        RingIsSet = False
        RaiseEvent InitEvent(Me, New System.EventArgs())
    End Sub

    'зарядка
    Public Sub Charge()
        If (IsCharging = False) Then
            IsCharging = True
            _timer.Start()
            RaiseEvent ChargeStartEvent(Me, New System.EventArgs()) 'вызов события начала зарядки
        Else
            IsCharging = False
            RaiseEvent ChargeStopEvent(Me, New System.EventArgs())
        End If
    End Sub

    'включение-выключение телефона
    Public Sub StartStop()
        If (IsOn = False) Then
            IsOn = True
            _timer.Start()
            _messageTimer.Start()
            RaiseEvent StartEvent(Me, New System.EventArgs())
        Else
            IsOn = False
            _timer.Stop()
            _messageTimer.Stop()
            'отключение звуков, которые могут проигрываться в данный момент
            If (_player.playState = WMPLib.WMPPlayState.wmppsPlaying) Then
                _player.controls.stop()
            End If
            RaiseEvent ShutDownEvent(Me, New System.EventArgs()) 'вызов события выключения телефона
        End If
    End Sub
    'активация звонка будильника
    Public Sub SetRingBell()
        If (RingIsSet) Then
            RingIsSet = False
            _ringTimer.Stop()
            _ringTimer.Enabled = False 'активация таймера проверки будильника
            'If (_player.playState = WMPLib.WMPPlayState.wmppsPlaying) Then
            '    _player.controls.stop()
            'End If
        Else
            _timerStartTime = DateTime.Now.ToString("HH:mm")
            _player.currentMedia = _player.newMedia(GetRingBellSound()) 'получает тек элемент коллекции
            _player.controls.stop()
            _ringTimer.Enabled = True
            _ringTimer.Start()
            _
            RingIsSet = True
        End If

    End Sub

    'получение полных путей для звуковых файлов
    'будильник
    Protected Overridable Function GetRingBellSound() As String
        Return Application.StartupPath & "\Sounds\old_ringbell.mp3"
    End Function

    'разрядился телефон
    Protected Overridable Function GetLowBatterySound() As String
        Return Application.StartupPath & "\Sounds\old_lowbattery.mp3"
    End Function

    'смс
    Protected Overridable Function GetSmsSound() As String
        Return Application.StartupPath & "\Sounds\old_message.mp3"
    End Function
    'подсчет непрочитанных сообщений
    Public Function GetUnreadMessagesCount() As Integer
        Dim count As Integer = 0
        For i = 0 To MessageList.Count - 1 Step 1
            If (MessageList(i).IsUnread) Then
                count += 1
            End If
        Next
        Return count
    End Function
#End Region

#Region "события"
    'телефон включился
    Public Event StartEvent(ByVal sender As Object, ByVal e As EventArgs)
    'телефон выключился
    Public Event ShutDownEvent(ByVal sender As Object, ByVal e As EventArgs)
    'зарядка началась
    Public Event ChargeStartEvent(ByVal sender As Object, ByVal e As EventArgs)
    '-//- закончилась
    Public Event ChargeStopEvent(ByVal sender As Object, ByVal e As EventArgs)
    'уровень заряда изменился
    Public Event BatteryLevelChangedEvent(ByVal sender As Object, ByVal e As EventArgs)
    'инициализация завершена
    Public Event InitEvent(ByVal sender As Object, ByVal e As EventArgs)
    'уровень заряда небольшой
    Public Event BatteryLow(ByVal sender As Object, ByVal e As EventArgs)
    'сообщение получено
    Public Event MessageRecieved(ByVal sender As Object, ByVal e As EventArgs)

#End Region

#Region "обработчики"
    ' обработчик заряда
    Private Sub ChargeHandler(ByVal sender As Object, ByVal e As ElapsedEventArgs)
        If (IsCharging = False And _batteryLevel > 0) Then
            BatteryLevel -= 1
            'если заряда телефона < 20, то необходимо зарядить
            If (_batteryLevel < 20 And _isLowBattery = False) Then
                'сообщение показывается 1 раз
                If (Not _isBatteryLowMsgShown) Then
                    _isBatteryLowMsgShown = True
                    MsgBox("Батарея разряжена. Включите в сеть, чтобы зарядить.")
                End If

                _isLowBattery = True
                RaiseEvent BatteryLow(Me, New System.EventArgs()) 'вызов события небольшого уровня заряда
            End If


        ElseIf (IsCharging = True And _batteryLevel < 100) Then
            BatteryLevel += 1
            If (_batteryLevel >= 20 And _isLowBattery = True) Then
                _isLowBattery = False
                _isBatteryLowMsgShown = False
                _isLowBatteryPlayed = False
                RaiseEvent BatteryLow(Me, New System.EventArgs())
            End If
        End If
    End Sub

    'проверка будильника
    Private Sub CheckRingBellTime(ByVal sender As Object, ByVal e As ElapsedEventArgs)
        'помимо времени проверяется, что ничего не звучит из плеера
        
        If (DateTime.Now.ToString("HH:mm") >= _ringTime.ToString("HH:mm") And
            _timerStartTime.ToString("HH:mm") < RingTime.ToString("HH:mm") And
            _IsRingBelling = False
        ) Then
            If (_player.playState = WMPLib.WMPPlayState.wmppsPlaying) Then
                _player.controls.stop()
            End If
            _player.currentMedia = _player.newMedia(GetRingBellSound())
            _IsRingBelling = True
            _player.controls.play()
        End If
        If (_isLowBattery) Then
            _isLowBattery = False
        End If

    End Sub

    'обработчик небольшого заряда телефона
    Private Sub OnBatteryLow(ByVal sender As Object, ByVal e As EventArgs) Handles Me.BatteryLow
        If (_isLowBattery) Then

            If (_player.playState = WMPLib.WMPPlayState.wmppsPlaying) Then
                _player.controls.stop()
            End If
            If (Not _isLowBatteryPlayed) Then
                _player.currentMedia = _player.newMedia(GetLowBatterySound())
                _player.controls.play()
                _isLowBatteryPlayed = True
            End If

            
        End If

    End Sub

    'генерация и добавление сообщений
    Protected Overridable Sub CheckMessageRecieve(ByVal sender As Object, ByVal e As ElapsedEventArgs)
        If (MessageList.Count < 10) Then
            MessageList.Add(_generator.GenerateExtended(Me))
            If (_player.playState <> WMPLib.WMPPlayState.wmppsPlaying) Then
                _player.currentMedia = _player.newMedia(GetSmsSound())
                _player.controls.play()
            End If
            RaiseEvent MessageRecieved(Me, New System.EventArgs())
        Else
            _messageTimer.Enabled = False
            _messageTimer.Stop()
        End If
    End Sub

#End Region

End Class
